`include "chunjun_define.sv" 
`include "chunjun_lib_define.sv" 
 
//===================================================================
// File Name   : wing_cbb_priority_queue.sv
// Date        : 
// Description :
//
//   MODE==0: find first one from LSB(least-significant bit) to MSB(most-significant bit).
//   MODE==1: find first one from MSB(most-significant bit) to LSB(least-significant bit).
//
//===================================================================

module wing_cbb_priority_queue #(
    parameter MODE  = 0, 
    parameter WIDTH = 8,
    parameter LOCK  = 0
) (
    input  logic             clk  ,
    input  logic             rst_n,
    input  logic             lock ,
    input  logic [WIDTH-1:0] vec_i,
    output logic [WIDTH-1:0] onehot_o
);

logic [WIDTH-1:0] vec_adj_or;
logic [WIDTH-1:0] onehot_mask;
logic             lock_vld_set;
logic             lock_vld_clr;
logic             lock_vld_en ;
logic             lock_arb_en ;
logic             lock_vld_d  ;
logic             lock_vld_q  ;
logic [WIDTH-1:0] lock_arb_d  ;
logic [WIDTH-1:0] lock_arb_q  ;
 
if (MODE == 0) begin : FF1_LOW
  assign vec_adj_or[0] = 1'b0;

  for (genvar i=1; i<WIDTH; i++) begin : G_ITER_L
    assign vec_adj_or[i] = vec_i[i-1] | vec_adj_or[i-1];
  end

end else begin : FF1_HIGH
  assign vec_adj_or[WIDTH-1] = 1'b0;
 
  for(genvar i=WIDTH-2; i>=0; i--) begin : G_ITER_H
    assign vec_adj_or[i] = vec_i[i+1] | vec_adj_or[i+1];
  end
end

assign onehot_mask = vec_i & ~vec_adj_or;
 
if (LOCK == 1) begin : g_priority_lock
//lock
assign lock_vld_set    = lock                        ;
assign lock_vld_clr    = lock_vld_q & ~lock          ;
assign lock_vld_en     = lock_vld_set | lock_vld_clr ;
assign lock_vld_d      = lock_vld_set                ;
`WDFFER(lock_vld_q, lock_vld_d, lock_vld_en, clk, rst_n)

assign lock_arb_en = ~lock_vld_q & lock ;
assign lock_arb_d  = onehot_mask  ; 
`WDFFER(lock_arb_q, lock_arb_d, lock_arb_en, clk, rst_n)

assign onehot_o = lock_vld_q ? lock_arb_q : onehot_mask ; 
end else begin : g_priority_unlock
assign onehot_o = onehot_mask; 
end

endmodule
`include "chunjun_undefine.sv" 
